#include <SFML/Network.hpp>
#include "../shared/network.hpp"
#include "ServerPlayer.hpp"
#include "server.hpp"

#include <iostream>
#include <vector>

using namespace std;

vector<class ServerPlayer> clients;

int main()
{
    sf::Randomizer rand;

    sf::SocketUDP Server;

    if (!Server.Bind(4567))
        return EXIT_FAILURE;

    while(true)
    {
        sf::IPAddress IP;
        sf::Uint16 Port;
        sf::Packet Packet;
        if (Server.Receive(Packet, IP, Port) != sf::Socket::Done)
            return EXIT_FAILURE;

        sf::Uint8 type = Packet_Type(Packet);
        if(type == PKTYPE_CLT_PLMOVE)
        {
            std::cout << "Got move Packet" << std::endl;

            struct PKCONTENT_CLT_PLMOVE pkcontent = PK_CLT_PLMOVE(Packet);

            ServerPlayer& cl = GetServerPlayerByIP(IP,clients);

            sf::Vector2f current_pos;
            sf::Vector2f new_pos;

            float current_rotation;
            float new_rotation;

            current_rotation = cl.GetRotation();
            current_pos = cl.GetPosition();

            new_pos.x = current_pos.x + pkcontent.x;
            new_pos.y = current_pos.y + pkcontent.y;
            new_rotation = current_rotation + pkcontent.rotate;

            cl.SetRotation(new_rotation);
            cl.SetPosition(new_pos);

            sf::Packet move = PK_SRV_PLPOS(cl.GetPid(), new_pos.x, new_pos.y, new_rotation);
            broadcast(Server,move,clients);
        }
        else if(type == PKTYPE_CLT_CONNECT)
        {
            ServerPlayer temp;
            temp.Ip = IP;
            temp.Port = Port;
            temp.SetPosition(sf::Vector2f(0,0));
            temp.SetRotation(0);
            sf::Int32 pid = rand.Random(0,2000000);
            temp.SetPid(pid);
            cout << "Client connected, PID " << pid << endl;
            clients.push_back(temp);

            sf::Packet connect = PK_SRV_PLCONNECT(pid);
            broadcast(Server,connect,clients);
            for(vector<class ServerPlayer>::iterator iter = clients.begin(); iter != clients.end(); ++iter)
            {
                sf::Int32 ClPid = iter->GetPid();
                sf::IPAddress& ClIp = iter->Ip;
                sf::Uint16& Port = iter->Port;
                if(pid != ClPid)
                {
                    sf::Packet connect = PK_SRV_PLCONNECT(ClPid);
                    Server.Send(connect,ClIp,Port);
                }

                sf::Packet pos = PK_SRV_PLPOS(ClPid,iter->GetPosition().x,iter->GetPosition().y,iter->GetRotation());
                Server.Send(pos,ClIp,Port);

            }
        }
        else if(type == PKTYPE_CLT_DISCONNECT)
        {
            RemoveFromVector(IP,clients);
            sf::Packet discon = PK_SRV_PLDISCONNECT(GetServerPlayerByIP(IP,clients).GetPid());
            broadcast(Server,discon,clients);
        }
    }


    /*sf::SelectorTCP Selector;
    if (!Listener.Listen(4567))
        return EXIT_FAILURE;

    Selector.Add(Listener);
    while (true)
    {
        unsigned int NbSockets = Selector.Wait();

        for (unsigned int i = 0; i < NbSockets; ++i)
        {
            sf::SocketTCP Socket = Selector.GetSocketReady(i);
            if (Socket == Listener)
            {
                sf::IPAddress Address;
                sf::SocketTCP Cl_sock;
                Listener.Accept(Cl_sock, &Address);
                sf::Int32 pid = rand.Random(0,20000000);
                std::cout << "Client connected ! (" << Address << ")" << " (" << pid << ")" << std::endl;

                ServerPlayer cl;
                cl.Sock = Cl_sock;
                cl.Ip = Address;
                cl.SetPid(pid);
                clients.push_back(cl);
                Selector.Add(Cl_sock);

                broadcast(PK_SRV_PLCONNECT(cl.GetPid()),clients);
                for(vector<class ServerPlayer>::iterator iter = clients.begin(); iter != clients.end(); ++iter)
                {
                    sf::Packet connect = PK_SRV_PLCONNECT(iter->GetPid());
                    Cl_sock.Send(connect);
                    sf::Packet pos = PK_SRV_PLPOS(iter->GetPid(),iter->GetPosition().x,iter->GetPosition().y,iter->GetRotation());
                    Cl_sock.Send(pos);
                }
            }
            else
            {
                sf::Packet Packet;
                if (Socket.Receive(Packet) == sf::Socket::Done)
                {
                    sf::Uint8 type;
                    type = Packet_Type(Packet);
                    if(type == PKTYPE_CLT_PLMOVE)
                    {
                        std::cout << "Got move Packet" << std::endl;
                        struct PKCONTENT_CLT_PLMOVE pkcontent;
                        pkcontent = PK_CLT_PLMOVE(Packet);
                        ServerPlayer& cl = GetServerPlayerBySocket(Socket,clients);
                        sf::Vector2f current_pos;
                        sf::Vector2f new_pos;
                        float current_rotation;
                        float new_rotation;
                        current_rotation = cl.GetRotation();
                        current_pos = cl.GetPosition();
                        new_pos.x = current_pos.x + pkcontent.x;
                        new_pos.y = current_pos.y + pkcontent.y;
                        new_rotation = current_rotation + pkcontent.rotate;
                        cl.SetRotation(new_rotation);
                        cl.SetPosition(new_pos);
                        broadcast(PK_SRV_PLPOS(cl.GetPid(), new_pos.x, new_pos.y, new_rotation),clients);
                    }
                }
                else
                {
                    sf::Int32 pid = GetServerPlayerBySocket(Socket,clients).GetPid();
                    RemoveFromVector(Socket,clients);
                    Selector.Remove(Socket);
                    broadcast(PK_SRV_PLDISCONNECT(pid),clients);
                }
            }
        }
    }*/
}
